package org.lvxiao.example.redis;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Component;

@Component
public class RedisScriptService {

	final static Logger log = LoggerFactory.getLogger(RedisScriptService.class);

	@Autowired
	private RedisTemplate redisTemplate;
	private Map<String, DefaultRedisScript<List>> scripts = new HashMap<>();
	private StringRedisSerializer keySerializer = new StringRedisSerializer();
	private final static String SCRIPT_DIR = "redis-lua";

	/**
	 * 启动时加载classpath下的redis-lua目录下指定的脚本, 脚本名称配置 eg:redis.script.names=a.lua,b.lue
	 */
	@PostConstruct
	public void init() {
		log.info("加载redis-lua脚本-开始");
		int loadCount = 0;
		PathMatchingResourcePatternResolver pathFinder = new PathMatchingResourcePatternResolver();
		try {
			Resource[] resources = pathFinder.getResources("classpath*:redis-lua/**/*.lua");
			if (resources == null || resources.length == 0) {
				log.info("加载redis-lua脚本-结束， 没有在classPath/redis-lua目录中找到lua脚本");
				return;
			}

			for (Resource resource : resources) {
				if (resource == null) {
					continue;
				}
				String filename = resource.getFilename();
				log.info("加载redis-lua脚本, 脚本名称:[{}]", filename);
				DefaultRedisScript<List> redisScript = new DefaultRedisScript<>();
				redisScript.setResultType(List.class);
				redisScript.setScriptSource(new ResourceScriptSource(resource));
				scripts.put(filename.substring(0, filename.length() - 4), redisScript);
				loadCount++;
			}
		} catch (IOException e) {
			log.error("加载redis-lua脚本-异常", e);
			throw new RuntimeException(e);
		}

		log.info("加载redis-lua脚本-结束, 成功加载[{}]个", loadCount);
	}

	@SuppressWarnings("unchecked")
	public List execute(String scriptName, List<Object> keys, List<String> argvList) {
		DefaultRedisScript<List> defaultRedisScript = scripts.get(scriptName);
		return (List) redisTemplate.execute(defaultRedisScript, keySerializer, keySerializer, keys, argvList.toArray());
	}
}
